import fs from 'fs';
import { Logger } from '../utils/logger.js';
import { fileURLToPath } from 'url';
import config from '../utils/config.js';
import { execAsync } from '../utils/exec.js';

const logger = new Logger('[conf:valid]');

// 验证脚本一致性
function validateScripts() {
  logger.info('🔍 开始验证脚本一致性...');

  const yamlScripts = config.yamlConfig;
  const packageJson = config.packageJson;
  const packageScripts = packageJson.scripts || {};

  const errors = [];
  const warnings = [];
  const info = [];

  // 获取所有脚本名称
  const yamlScriptNames = Object.keys(yamlScripts);
  const packageScriptNames = Object.keys(packageScripts);

  // 忽略列表 - 这些脚本不需要在 YAML 中定义
  const ignoreList = [
    'test', // 测试命令可能只在 package.json 中
    'lint', // 代码检查
    'format', // 格式化
    'prepare', // npm 生命周期钩子
    'postinstall', // npm 生命周期钩子
    'preinstall', // npm 生命周期钩子
    'prepublishOnly', // npm 生命周期钩子
  ];

  // 1. 检查 YAML 中定义但 package.json 中没有的脚本
  yamlScriptNames.forEach((name) => {
    if (!packageScripts[name]) {
      errors.push({
        type: 'missing-in-package',
        name,
        message: `"${name}" 在 scripts.yaml 中定义，但不在 package.json 中`,
      });
    }
  });

  // 2. 检查 package.json 中有但 YAML 中没有文档的脚本
  packageScriptNames.forEach((name) => {
    if (!yamlScripts[name] && !ignoreList.includes(name)) {
      warnings.push({
        type: 'missing-in-yaml',
        name,
        message: `"${name}" 在 package.json 中，但没有在 scripts.yaml 中记录`,
      });
    } else if (!yamlScripts[name] && ignoreList.includes(name)) {
      info.push({
        type: 'ignored',
        name,
        message: `"${name}" 被忽略（在忽略列表中）`,
      });
    }
  });

  // 3. 检查命令内容是否一致
  yamlScriptNames.forEach((name) => {
    if (packageScripts[name]) {
      const yamlCommand = yamlScripts[name].command;
      const packageCommand = packageScripts[name];

      if (yamlCommand !== packageCommand) {
        warnings.push({
          type: 'command-mismatch',
          name,
          message: `"${name}" 命令不一致`,
          details: {
            yaml: yamlCommand,
            package: packageCommand,
          },
        });
      }
    }
  });

  // 4. 统计信息
  const stats = {
    totalInYaml: yamlScriptNames.length,
    totalInPackage: packageScriptNames.length,
    documented: yamlScriptNames.filter((n) => packageScripts[n]).length,
    undocumented: packageScriptNames.filter((n) => !yamlScripts[n] && !ignoreList.includes(n))
      .length,
    ignored: packageScriptNames.filter((n) => ignoreList.includes(n)).length,
  };

  // 输出结果
  logger.info('📊 统计信息:');
  logger.info(`  • YAML 中定义: ${stats.totalInYaml} 个脚本`);
  logger.info(`  • package.json 中: ${stats.totalInPackage} 个脚本`);
  logger.info(`  • 已记录文档: ${stats.documented} 个`);
  logger.info(`  • 未记录文档: ${stats.undocumented} 个`);
  logger.info(`  • 忽略的脚本: ${stats.ignored} 个`);
  logger.blank();

  // 显示错误
  if (errors.length > 0) {
    logger.error('错误 (需要修复):');
    errors.forEach((err) => {
      logger.error(`  • ${err.message}`);
      if (err.details) {
        logger.error(`    - YAML: ${err.details.yaml}`);
        logger.error(`    - Package: ${err.details.package}`);
      }
    });
    logger.blank();
  }

  // 显示警告
  if (warnings.length > 0) {
    logger.warning('警告 (建议修复):');
    warnings.forEach((warn) => {
      logger.warning(`  • ${warn.message}`);
      if (warn.details) {
        logger.warning(`    - YAML: "${warn.details.yaml}"`);
        logger.warning(`    - Package: "${warn.details.package}"`);
      }
    });
    logger.blank();
  }

  // 显示信息
  if (info.length > 0 && process.argv.includes('--verbose')) {
    logger.info('ℹ️  信息:');
    info.forEach((i) => {
      console.log(`  • ${i.message}`);
    });
    logger.blank();
  }

  // 生成修复建议
  if (errors.length > 0 || warnings.length > 0) {
    logger.info('修复建议:');

    if (errors.filter((e) => e.type === 'missing-in-package').length > 0) {
      logger.info('  1. 运行 `pnpm conf:sync` 同步 YAML 到 package.json');
    }

    if (warnings.filter((w) => w.type === 'missing-in-yaml').length > 0) {
      logger.info('  2. 在 scripts.yaml 中添加缺失的脚本文档');
      logger.info('     或者将它们添加到忽略列表中');
    }

    if (warnings.filter((w) => w.type === 'command-mismatch').length > 0) {
      logger.info('  3. 检查并更新不一致的命令');
      logger.info('     运行 `pnpm conf:sync` 使用 YAML 中的命令');
    }

    logger.blank();
  }

  // 决定退出码
  if (errors.length > 0) {
    logger.error('验证失败！发现 ' + errors.length + ' 个错误');
    process.exit(1);
  } else if (warnings.length > 0) {
    logger.warning('验证通过，但有 ' + warnings.length + ' 个警告');
    process.exit(0);
  } else {
    logger.success('完美！所有脚本都已同步且有文档');
    process.exit(0);
  }
}

// 可选：自动修复功能
async function autoFix() {
  logger.info('🔧 开始自动修复...');

  const yamlScripts = config.yamlConfig;
  const packageJson = config.packageJson;
  const packageScripts = packageJson.scripts || {};

  // 只修复 YAML 中有但 package.json 中没有的脚本
  let fixed = 0;
  Object.entries(yamlScripts).forEach(([name, info]) => {
    if (!packageScripts[name]) {
      packageScripts[name] = info.command;
      logger.success(`添加脚本: ${name}`);
      fixed++;
    } else if (packageScripts[name] !== info.command) {
      packageScripts[name] = info.command;
      logger.success(`更新脚本: ${name}`);
      fixed++;
    }
  });

  if (fixed > 0) {
    // 更新 package.json
    packageJson.scripts = packageScripts;
    const packagePath = config.packagePath;

    logger.info(`📝 写入: ${packagePath}`);
    await fs.writeFileSync(packagePath, JSON.stringify(packageJson, null, 2) + '\n');

    logger.info('🔄 prettier 格式化');
    try {
      await execAsync('pnpm', ['prettier', '-w', packagePath], {
        shell: true,
        silent: true,
      });
    } catch (error) {
      logger.warning('prettier 格式化 package.json 失败: ' + error.message);
    }

    logger.success(`自动修复了 ${fixed} 个问题`);
  } else {
    logger.success('没有需要修复的问题');
  }
}

// 主程序
const __filename = fileURLToPath(import.meta.url);
const isMain = process.argv[1] === __filename;

if (isMain) {
  const args = process.argv.slice(2);

  if (args.includes('--fix')) {
    autoFix();
  } else if (args.includes('--help')) {
    logger.info('📚 脚本验证工具');
    logger.info('用法:');
    logger.info('  pnpm validate [options]');
    logger.info('选项:');
    logger.info('  --fix      自动修复可以修复的问题');
    logger.info('  --verbose  显示详细信息（包括忽略的脚本）');
    logger.info('  --help     显示帮助信息');
    logger.info('示例:');
    logger.info('  pnpm validate           # 验证一致性');
    logger.info('  pnpm validate --fix     # 自动修复问题');
    logger.info('  pnpm validate --verbose # 显示详细信息');
    logger.info('说明:');
    logger.info('  此工具验证 scripts.yaml 和 package.json 中脚本的一致性。');
    logger.info('  它会检查：');
    logger.info('  1. YAML 中定义但 package.json 中缺失的脚本');
    logger.info('  2. package.json 中有但 YAML 中没有文档的脚本');
    logger.info('  3. 命令内容是否一致');
  } else {
    validateScripts();
  }
}

export { validateScripts, autoFix };
